﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace PROJECT_BOMBER.BLL
{
    // strategie de deplacement au clavier 1
    public class ControllerKeyboard : ControllerStrategy
    {

        #region Variable Etat Button + Fullscreen

        private static bool activeE = true;
        private static bool activeSpace = true;
        private static bool activeStart = true;
        private static bool fullscreen = false;

        #endregion

        public override void Control(ElementMove element1)
        {

            Exit(Keys.Escape ,Globals.Game);

            Zoom(Keys.PageDown, Keys.PageUp, PlayerIndex.One, Globals.Camera);

            Rotation(Keys.F11, Keys.F12,Keys.F10, (Character)element1);

            SpeedX(Keys.Q, Keys.D, Keys.LeftShift, (Character)element1);

            Fly(Keys.E, (Character)element1);

            Jump(Keys.Space, (Character)element1);

            Attack(Keys.A, (Character)element1);

            SpeedY(Keys.Z, Keys.S, Keys.LeftAlt, (Character)element1);

            Fullscreen(Keys.F1, Globals.GDM, Globals.Screen);


        }

        /// <summary>
        /// Fullscreens with the specified key1.
        /// </summary>
        /// <param name="key1">The key1.</param>
        /// <param name="graphics">The graphics.</param>
        /// <param name="screen">The size of screen.</param>
        /// <returns></returns>
        private static Vector2 Fullscreen( Keys key1, GraphicsDeviceManager graphics, Vector2 screen)
        {
            #region Key [F1] => Fullscreen
            if (!fullscreen && Keyboard.GetState(PlayerIndex.One).IsKeyDown(key1) && activeStart)
            {
                graphics.PreferredBackBufferWidth = (int)screen.X;
                graphics.PreferredBackBufferHeight = (int)screen.Y;
                graphics.ToggleFullScreen();
                activeStart = false;
                fullscreen = !fullscreen;
            }
            else if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key1) && activeStart)
            {
                graphics.PreferredBackBufferWidth = (int)screen.X - (160 * 3);
                graphics.PreferredBackBufferHeight = (int)screen.Y - (90 * 3);
                graphics.ToggleFullScreen();
                activeStart = false;
                fullscreen = !fullscreen;
            }
            if (Keyboard.GetState(PlayerIndex.One).IsKeyUp(key1))
            {
                activeStart = true;
            }
            #endregion
            return screen;
        }

        /// <summary>
        /// Speeds the Y.
        /// </summary>
        /// <param name="key1">The key1.</param>
        /// <param name="key2">The key2.</param>
        /// <param name="key3">The key3.</param>
        /// <param name="element1">The element1.</param>
        private static void SpeedY(Keys key1, Keys key2, Keys key3, Character element1)
        {
            #region {debug} Key [LeftAlt] => Allow Speed Y
            if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key3))
            {
                if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key1))
                {
                    element1.Speed = new Vector2(element1.Speed.X, -element1.Speedmax.X);
                }
                else if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key2))
                {

                    element1.Speed = new Vector2(element1.Speed.X, element1.Speedmax.X);
                }
                else
                {
                    element1.Speed = new Vector2(element1.Speed.X, 0);
                }
            }
            #endregion
        }

        private static void Attack(Keys key1, Character element1)
        {
            #region Key [A] => Attack
            if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key1) && element1.Speed.X != 0 && !element1.Fly)
            {
                element1.Attack = true;
            }
            else
            {
                element1.Attack = false;
            }
            #endregion
        }

        private static void Jump(Keys key1, Character element1)
        {
            #region Key [Space] => Jump & Double Jump & Jump right/left
            if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key1))
            {
                if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key1) && element1.Jump < 2 && activeSpace)
                {
                    if ((element1.Jump == 0 && element1.Onground > 0) || element1.Jump == 1)
                    {
                        element1.Speed = new Vector2(element1.Speed.X, -element1.Speedmax.Y / (element1.Gravity + element1.Jump));

                        element1.Jump++;
                        activeSpace = false;
                    }
                }
            }

            if (Keyboard.GetState(PlayerIndex.One).IsKeyUp(Keys.Space) && element1.Onground == 0)
            {
                activeSpace = true;
            }


            if (Keyboard.GetState(PlayerIndex.One).IsKeyUp(Keys.Space) && element1.Onground > 0)
            {
                activeSpace = true;
                element1.Jump = 0;
            }

            if (element1.JumpWall && element1.Jump == 2 && element1.Onground == 0 && Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Space) && activeSpace && element1.Speed.Y < element1.Speedmax.Y)
            {
                if (element1.Speed.X < 0)
                {
                    element1.JumpWall = false;
                    element1.Speed = new Vector2(element1.Speed.X + element1.Speedmax.X, -element1.Speedmax.Y / 6);
                    element1.ActiveSpeedX = false;
                    activeSpace = false;
                }
                else if (element1.Speed.X > 0)
                {
                    element1.JumpWall = false;
                    element1.Speed = new Vector2(element1.Speed.X - element1.Speedmax.X, -element1.Speedmax.Y / 6);
                    element1.ActiveSpeedX = false;
                    activeSpace = false;
                }
            }

            #endregion
        }

        private static void Fly(Keys key1, Character element1)
        {
            #region Key [E] => active/desactive Fly
            if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key1) && activeE && element1.Speed.Y < 0)
            {
                element1.Fly = !element1.Fly;
                activeE = false;
            }
            else if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key1) && activeE)
            {
                element1.Fly = false;
            }

            if (Keyboard.GetState(PlayerIndex.One).IsKeyUp(key1))
            {
                activeE = true;
            }
            #endregion
        }

        private static void SpeedX(Keys key1, Keys key2, Keys key3, Character element1)
        {
            int newSpeedX = (int)element1.Speed.X;

            #region Key [Q][D][MAJ] => X : Speed X
            if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key2))
            {
                if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key3) && element1.Speed.X < element1.Speedmin.X * 3 && element1.ActiveSpeedX)
                {
                    newSpeedX = (int)(element1.Speed.X + (element1.Speedmax.X * 10) / 30);
                }
                else if (element1.Speed.X < element1.Speedmax.X && element1.ActiveSpeedX)
                {
                    newSpeedX = (int)(element1.Speed.X + element1.Speedmin.X / element1.Inertia);
                }
            }
            else if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key1))
            {
                if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key3) && element1.Speed.X > -element1.Speedmin.X * 3 && element1.ActiveSpeedX)
                {
                    newSpeedX = (int)(element1.Speed.X + (-element1.Speedmax.X * 10) / 30);
                }
                else if (element1.Speed.X > -element1.Speedmax.X && element1.ActiveSpeedX)
                {
                    newSpeedX = (int)(element1.Speed.X - element1.Speedmin.X / element1.Inertia);
                }
            }
            else if (Keyboard.GetState(PlayerIndex.One).IsKeyUp(key1) && Keyboard.GetState(PlayerIndex.One).IsKeyUp(key2) && !element1.ActiveSpeedX)
            {
                element1.ActiveSpeedX = true;

                if (element1.Speed.X > 0)
                {
                    newSpeedX = (int)(element1.Speed.X - element1.Speedmin.X / element1.Inertia);
                }
                else
                {
                    newSpeedX = (int)(element1.Speed.X + element1.Speedmin.X / element1.Inertia);
                }
            }
            else
            {
                if (element1.Onground > 0)
                {
                    if (element1.Speed.X > element1.Speedmin.X / element1.Inertia)
                    {
                        newSpeedX = (int)(element1.Speed.X - element1.Speedmin.X / element1.Inertia);
                    }
                    else if (element1.Speed.X < -element1.Speedmin.X / element1.Inertia)
                    {
                        newSpeedX = (int)(element1.Speed.X + element1.Speedmin.X / element1.Inertia);
                    }
                    else
                    {
                        newSpeedX = 0;
                    }
                }
                else
                {
                    if (element1.Speed.X > element1.Speedmin.X / element1.Inertia)
                    {
                        newSpeedX = (int)(element1.Speed.X - element1.Speedmin.X / (element1.Inertia*3));
                    }
                    else if (element1.Speed.X < -element1.Speedmin.X / element1.Inertia)
                    {
                        newSpeedX = (int)(element1.Speed.X + element1.Speedmin.X / (element1.Inertia*3));
                    }
                    else
                    {
                        newSpeedX = 0;
                    }
                }
            }

            element1.Speed = new Vector2(newSpeedX, element1.Speed.Y);
            #endregion
        }

        private static void Rotation(Keys key1, Keys key2, Keys key3, Character element1)
        {
            #region Key [Up][Down][0] => Rotation character

            if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key1))
            {
                element1.Rotation += 0.1f;
            }
            if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key2))
            {
                element1.Rotation -= 0.1f;
            }
            if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key3))
            {
                element1.Rotation = 0;
            }

            #endregion
        }

        private static void Zoom(Keys key1, Keys key2, PlayerIndex player, Camera2d cam)
        {

           /* if (GamePad.GetState(player).ThumbSticks.Right.X > 0.7 || GamePad.GetState(player).ThumbSticks.Right.X < -0.7)
            {
                if (cam.Rotation + GamePad.GetState(player).ThumbSticks.Right.X / 200 >= -1 && cam.Zoom + GamePad.GetState(player).ThumbSticks.Right.X / 200 < 1)
                {
                    cam.Rotation += GamePad.GetState(player).ThumbSticks.Right.X / 200;
                }
            }*/

            if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key1))
            {
                cam.Zoom -= 0.001f;
            }
            if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key2))
            {
                cam.Zoom += 0.001f;
            }
        }

        private static void Exit(Keys key1, Game game)
        {
            if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(key1))
            {
                game.Exit();
            }
        }

    }
}
